/**
 * @file list.h
 * @author lcz (you@domain.com)
 * @brief
 * @version 0.1
 * @date 2022-10-22
 *
 * @copyright Copyright (c) 2022
 *
 */

#ifndef LIST_H
#define LIST_H

#include "tools/log.h"
#include "comm/types.h"


// 定义结构体
/**
 * 利用链表的地址，推导结构体的地址，由于结构体中含有链表结点，这些链表结点又被list组织成地址
 *
 * 计算偏移 假定地址在0处，取到的node地址的就是偏移
 * (uint32_t)&(struct task_t *)0->node
 * 计算地址
 * (uint32_t)node-(uint32_t)&(struct task_t *)0->node
 *
 */

typedef struct _list_node_t
{
    struct _list_node_t *pre;
    struct _list_node_t *next;
} list_node_t;

typedef struct _list_t
{
    list_node_t *first;
    list_node_t *last;
    int count;
} list_t;


#define offset_in_parent(parent_type, node_name) \
    ((uint32_t) & (((parent_type *)0)->node_name))

#define parent_addr(node, parent_type, node_name) \
    ((uint32_t)node - (offset_in_parent(parent_type, node_name)))

// 实际上这个函数将目标地址转换为对应的类型
#define list_node_parent(node, parent_type, node_name) \
    (parent_type *)(node?parent_addr(node, parent_type, node_name):0)




static inline void list_node_init(list_node_t *node)
{
    node->pre = node->next = (list_node_t *)0;
}
static inline list_node_t *list_node_pre(list_node_t *node)
{
    return node->pre;
}
static inline list_node_t *list_node_next(list_node_t *node)
{
    return node->next;
}



// list_t methods
static inline int list_is_empty(list_t *list)
{
    return list->count == 0;
}
static inline int list_count(list_t *list)
{
    return list->count;
}
static inline list_node_t *list_first(list_t *list)
{
    return list->first;
}
static inline list_node_t *list_last(list_t *list)
{
    return list->last;
}

// insert
void list_insert_first(list_t *list, list_node_t *node);
void list_insert_last(list_t *list, list_node_t *node);

// remove
list_node_t *list_remove_first(list_t *list);
list_node_t *list_remove(list_t *list, list_node_t *node);

void list_init(list_t *list);
void list_test(void);
#endif
